package springboot.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springboot.bean.Stack;
import springboot.bean.StackExample;
import springboot.bean.StackTask;
import springboot.bean.StackTaskExample;
import springboot.http.HttpClientTools;
import springboot.kernel.KernelTools;
import springboot.mapper.StackMapper;
import springboot.mapper.StackTaskMapper;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.time.*;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Service
public class StackService {

    @Autowired
    StackMapper stackMapper;
    @Autowired
    StackTaskMapper stackTaskMapper;

    StackExample ex=null;
    StackExample.Criteria criteria=null;
    Stack stack=null;
    KernelTools km = new KernelTools();
    String v1OrderName=null;
    StackTaskExample taskExample=null;
    StackTaskExample.Criteria taskCriteria=null;
    StackTask stackTask=null;
    List<StackTask> list=null;
    int A=0;
    @Scheduled(fixedDelay = 1000*2)
    public void changeStateTask(){
        if (A==0){//不再更新orderName
            v1OrderName=km.getTranspotOrder("Vehicle-0001");
        }
        /*使用ifelse有一个弊端，任务结束条件不满足进不去*/
        if(!v1OrderName.equals("N/A")) {
            if(!v1OrderName.startsWith("Park") && !v1OrderName.startsWith("Recharge")
                && !v1OrderName.startsWith("TOrder") && !v1OrderName.startsWith("Move")) {
                //获得地堆放货地点属性
                String end=km.getPropertyByOrder(v1OrderName);
                /*不再跟新v1OrderName,直到任务结束或者失败*/
                if (A==0){
                    A=1;
                }
                String v1orderStatus = km.getOrderStatus(v1OrderName);
                if(v1orderStatus.equals("FINISHED")) {
                    ex=new StackExample();
                    criteria=ex.createCriteria();
                    criteria.andPositionEqualTo(end);
                    stack=new Stack();
                    stack.setStatus("YES");
                    stackMapper.updateByExampleSelective(stack,ex);
                    try {
                        HttpClientTools.sendGetData("http://localhost:9998/showAllStack","utf-8");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    taskExample=new StackTaskExample();
                    taskCriteria=taskExample.createCriteria();
                    taskCriteria.andStatusEqualTo("0");
                    taskCriteria.andToEqualTo("60"+end.substring(2));
                    list=stackTaskMapper.selectByExample(taskExample);
                    if(list.size()==0){
                        System.out.println("没有缓存的任务");
                    }else{
                        list.get(0).setStatus("1");
                        stackTaskMapper.updateByPrimaryKey(list.get(0));
                        System.out.println("任务完成,生成其它任务");
                    }
                    A=0;
                }
                if(v1orderStatus.equals("FAILED")) {
                    ex=new StackExample();
                    stack=new Stack();
                    criteria=ex.createCriteria();
                    criteria.andPositionEqualTo(end);
                    stack.setStatus("YES");
                    stackMapper.updateByExampleSelective(stack,ex);
                    try {
                        HttpClientTools.sendGetData("http://localhost:9998/showAllStack","utf-8");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    taskExample=new StackTaskExample();
                    taskCriteria=taskExample.createCriteria();
                    taskCriteria.andStatusEqualTo("0");
                    taskCriteria.andToEqualTo("60"+end.substring(2));
                    list=stackTaskMapper.selectByExample(taskExample);
                    /*以下这段代码的意思是
                    * 判断list是否为null,如果是null就让orElse后的值传给list
                    * 可以加.map来依次判断一个链式的编程条件是否有为null的值
                    * 这是Java8中的一个语法糖
                    * */
                    /*list=Optional.ofNullable(list).orElse(null);*/
                    if(list.size()==0){
                        System.out.println("没有缓存的任务");
                    }else{
                        list.get(0).setStatus("1");
                        stackTaskMapper.updateByPrimaryKey(list.get(0));
                        System.out.println("任务失败,生成其它任务");
                    }
                    A=0;
                }
            }
        }
    }


    StackExample.Criteria stackCriteria=null;
    Stack stack1=null;
    KernelTools kernelTools = new KernelTools();
    List<Stack> stackList=null;
    /*这里有一个问题
    * 每个两秒去读数据库,数据量小一点没关系,万一数据量很大,这特么几乎是灾难性的
    * 使用阿里的canal来解决这个问题
    * canal利用mysql的bin log去和主库建立一个连接,去监听主库数据的变化
    * 然后把数据通过各种方式传送给程序[canal自身支持tcp链接,建立链接直接获取变化数据]
    * [其它方式就是canal把变化的数据插入到消息中间件中]
    * */
    public void creatOrderTask(StackTask task) throws IOException {
        StackTaskExample.Criteria criteria=null;
        /*1表示有任务,查看去往哪里,依据它的去向看任务能不能创建*/
        String start=task.getFrom();
        String end=task.getTo();
        stack=stackMapper.selectMaxLineINNO(end);
        if(stack.getMaxLine().equals("0")) {//表明该列没有货物
            kernelTools.CreateOrderOneStation(start,"80"+end.substring(2), "test"+UUID.randomUUID());
            /*改变任务站点*/
            ex=new StackExample();
            stackCriteria=ex.createCriteria();
            stackCriteria.andPositionEqualTo("80"+end.substring(2));
            stack1=new Stack();
            stack1.setStatus("TOUSE");
            stackMapper.updateByExampleSelective(stack1,ex);
            HttpClientTools.sendGetData("http://localhost:9998/showAllStack","utf-8");
            System.out.println("最里面的任务发送成功,并删除该列任务");
            stackTaskMapper.deleteByPrimaryKey(task.getId());
        }else if(stack.getMaxLine().equals("1")){
            /*查询80的该货物是否是TOUSE*/
            ex=new StackExample();
            stackCriteria=ex.createCriteria();
            stackCriteria.andPositionEqualTo("80"+end.substring(2));
            stackCriteria.andStatusEqualTo("TOUSE");
            stackList=stackMapper.selectByExample(ex);
            if (stackList.size()==0){
                kernelTools.CreateOrderOneStation(start,"70"+end.substring(2),"test"+UUID.randomUUID());
                /*改变任务站点*/
                ex=new StackExample();
                stackCriteria=ex.createCriteria();
                stackCriteria.andPositionEqualTo("70"+end.substring(2));
                stack1=new Stack();
                stack1.setStatus("TOUSE");
                stackMapper.updateByExampleSelective(stack1,ex);
                HttpClientTools.sendGetData("http://localhost:9998/showAllStack","utf-8");
                System.out.println("中间的任务发送成功,并删除该列任务");
                stackTaskMapper.deleteByPrimaryKey(task.getId());
            }else{/*有正在使用的货位，wcs抢先了*/
                /*更改其状态为0*/
                taskExample=new StackTaskExample();
                criteria=taskExample.createCriteria();
                criteria.andIdEqualTo(task.getId());
                stackTask=new StackTask();
                stackTask.setStatus("0");
                stackTaskMapper.updateByExampleSelective(stackTask,taskExample);
                System.out.println("不好意思，被抢先了,请稍等==中间");
            }
        }else if(stack.getMaxLine().equals("2")){
            /*查询80的该货物是否是TOUSE*/
            ex=new StackExample();
            stackCriteria=ex.createCriteria();
            stackCriteria.andPositionEqualTo("70"+end.substring(2));
            stackCriteria.andStatusEqualTo("TOUSE");
            stackList=stackMapper.selectByExample(ex);
            if (stackList.size()==0){
                kernelTools.CreateOrderOneStation(start,"60"+end.substring(2),"test"+UUID.randomUUID());
                /*改变任务站点*/
                ex=new StackExample();
                stackCriteria=ex.createCriteria();
                stackCriteria.andPositionEqualTo("60"+end.substring(2));
                stack1=new Stack();
                stack1.setStatus("TOUSE");
                stackMapper.updateByExampleSelective(stack1,ex);
                HttpClientTools.sendGetData("http://localhost:9998/showAllStack","utf-8");
                System.out.println("最外层的任务发送成功,并删除该列任务");
                stackTaskMapper.deleteByPrimaryKey(task.getId());
            }else{/*有正在使用的货位，wcs抢先了*/
                /*更改其状态为0*/
                taskExample=new StackTaskExample();
                criteria=taskExample.createCriteria();
                criteria.andIdEqualTo(task.getId());
                stackTask=new StackTask();
                stackTask.setStatus("0");
                stackTaskMapper.updateByExampleSelective(stackTask,taskExample);
                System.out.println("不好意思，被其它任务抢先了,请稍等==最外层");
            }
        }else if(stack.getMaxLine().equals("3")){
            taskExample=new StackTaskExample();
            criteria=taskExample.createCriteria();
            criteria.andIdEqualTo(task.getId());
            stackTask=new StackTask();
            stackTask.setStatus("0");
            stackTaskMapper.updateByExampleSelective(stackTask,taskExample);
            System.out.println("请清空货位");
        }
    }
    /*
    *对标注此@Transactional的方法，进行事务管理
    * rollbackFor表示遇到什么异常就回滚
    * noRollbackFor表示遇到此异常不进行回滚
    * */
    @Transactional(rollbackFor = {RuntimeException.class},noRollbackFor = {IllegalArgumentException.class})
    public void transactionTest(){

    }

    @PostConstruct
    public void firstStart(){
        /*Stack stack=new Stack();
        stack.setId(190);
        stack.setStatus("40");
        *//*java8中判断空指针常用的方法*//*
        String position=Optional.ofNullable(stack).map(Stack::getPosition).orElse("0");
        Optional<Stack> optionalStack=Optional.ofNullable(stack);
        Stack stack2=optionalStack.orElse(null);
        System.out.println(stack2);*/
/*线程安全*/
//        LocalDate now = LocalDate.now();
//        LocalDate now1 = LocalDate.now(Clock.systemUTC());
//        System.out.println(now);
//        System.out.println(now1);
//        LocalDate of = LocalDate.of(2019, 3, 6);
//        //严格按照ISO yyyy-MM-dd验证，03写成3都不行
//        LocalDate parse = LocalDate.parse("2019-03-06");
//        System.out.println(of);
//        System.out.println(parse);
//
//        LocalTime nowtime = LocalTime.now();
//        System.out.println(nowtime);
//
//        LocalDateTime localDateTime=LocalDateTime.of(LocalDate.now(), LocalTime.now(Clock.system(ZoneId.systemDefault())));
//        System.out.println(localDateTime);
    }
}
